package com.attendance.service;

import com.attendance.annotation.Supplement;
import com.attendance.annotation.type.OperationType;
import com.attendance.java.StringUtils;
import com.attendance.mapper.DepartUserMapper;
import com.attendance.mapper.DepartmentMapper;
import com.attendance.pojo.DepartUser;
import com.attendance.pojo.Department;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 部门服务
 *
 * @author 今朝
 * @date 2021/03/17
 */
@Service
public class DepartmentServiceImpl {
    @Autowired
    DepartmentMapper departmentMapper;
    @Autowired
    DepartUserMapper departUserMapper;

    public Department selectById(Long id) {
        return departmentMapper.selectById(id);
    }

    public List<Department> getList() {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        return departmentMapper.selectList(queryWrapper);
    }

    public Boolean delete(Long id) throws Exception {
        if (departmentMapper.findDepartNumsByParentId(id) != 0) {
            throw new Exception("不能删除非根节点");
        }
        return departmentMapper.deleteById(id) != 0;
    }

    public Page<Department> getListPage(Integer pageNum, Integer limit) {
        Page<Department> page = new Page<>(pageNum, limit);
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        departmentMapper.selectPage(page, queryWrapper);
        return page;
    }

    public Page<Department> getListPage(Integer pageNum, Integer limit, String name) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", name);
        queryWrapper.orderByAsc("idx");
        Page<Department> page = new Page<>(pageNum, limit);
        departmentMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Supplement(type = OperationType.UPDATE)
    public Boolean updateById(Department department) {
        return departmentMapper.updateById(department) != 0;
    }

    @Supplement(type = OperationType.PUT)
    public Boolean add(Department department) {
        return departmentMapper.insert(department) != 0;
    }

    public List<Department> getRoots() {
        return departmentMapper.findDepartTreeRoots();
    }

    public List<Long> getIdsByParentId(Long id) {
        List<Long> ids = new ArrayList<>();
        Department department = new Department();
        department.setId(id);
        department.setChildren(departmentMapper.findDepartByParentId(id));
        dpsIds(department, ids);
        QueryWrapper<DepartUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("depart_id", ids);
        List<DepartUser> departUsers = departUserMapper.selectList(queryWrapper);
        return departUsers.stream().map(DepartUser :: getUserId).collect(Collectors.toList());
    }

    public List<Long> getParentIdsById(Long id) {
        List<Long> ids = new ArrayList<>();
        long dId = id;
        while (true) {
            ids.add(dId);
            dId = departmentMapper.selectById(dId).getParentId();
            if (dId == - 1) {
                break;
            }
        }
        QueryWrapper<DepartUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("depart_id", ids);
        List<DepartUser> departUsers = departUserMapper.selectList(queryWrapper);
        return departUsers.stream().map(DepartUser :: getUserId).collect(Collectors.toList());
    }

    public void dpsIds(Department department, List<Long> ids) {
        ids.add(department.getId());
        for (Department child : department.getChildren()) {
            dpsIds(child, ids);
        }
    }

    public Boolean binding(String uIds, Long dId) {
        List<Long> userIds = StringUtils.strToIdsByComma(uIds);
        for (Long uid : userIds) {
            QueryWrapper<DepartUser> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", uid);
            departUserMapper.delete(queryWrapper);
            departUserMapper.insert(new DepartUser(dId, uid));
        }
        return true;
    }

    public List<String> getDepartNameByIds(List<Long> ids) {
        QueryWrapper<Department> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("idx");
        queryWrapper.in("id", ids);
        List<Department> departments = departmentMapper.selectList(queryWrapper);
        return departments.stream().map(Department :: getName).collect(Collectors.toList());
    }
}
